<template>
  <m-modal 
    v-model="visible" 
    :confirmDisabled="isRequired && !selectedNode"
    mask
    title="属性"
    :center="true"
    @ok="handleOk" 
    @cancel="handleCancel">
    <m-attr-tip type="radio" />

    <a-tabs v-model="curTab" type="card" class="_tab">
      <a-tab-pane key="tree" tab="树" style="overflow-y:auto;border: 1px solid #D9D9D9;">
        <div class="g-pd-lr-20 g-pd-b-20 g-pd-t-10" style="height:400px;">
          <a-select
            show-search
            placeholder="搜索"
            option-filter-prop="children"
            style="width: 100%;margin-bottom:10px"
            size="small"
            @change="handleSelectChange"
            @search="handleSelectSearch"
          >
            <a-icon slot="suffixIcon" type="search" />
            <a-select-option v-for="(item,index) in selectOptions" :key="index"  :value="item.id" :title="item.label">
              {{item.label}}
            </a-select-option>
          </a-select>
          <div style="height:350px;overflow:auto">
            <m-select-tree
              :treeData="treeData"
              @select="handleTreeSelect"
            />
          </div>
        </div>
      </a-tab-pane>
      <a-tab-pane key="list" tab="列表" style="overflow-y:auto;border: 1px solid #D9D9D9;">
        <div  class="g-pd-lr-20 g-pd-b-20 g-pd-t-10" style="height:400px;">
          <a-select
            show-search
            placeholder="搜索"
            option-filter-prop="children"
            style="width: 100%;margin-bottom:10px"
            size="small"
            @change="handleSelectChange"
            @search="handleSelectSearch"
          >
            <a-icon slot="suffixIcon" type="search" />
            <a-select-option v-for="(item,index) in selectOptions" :key="index"  :value="item.id" :title="item.label">
              {{item.label}}
            </a-select-option>
          </a-select>
          <div style="height:350px;overflow:auto">
            <m-list
              :selectedNodes="[selectedNode]"
              :list="list"
              @select="handleListSelect"
            />
          </div>
        </div>
      </a-tab-pane>
    </a-tabs>
  </m-modal>
</template>
<script>
import { Portal } from 'src/components/common/Portal.vue';
import { debounce } from 'lodash';
import { treeForEach, initTree, findNodeByValue } from 'src/util/common';
import Modal from 'src/components/common/CustomModal';
import AttrTip from '../comps/AttrTip';
import SelectTree from '../comps/SelectTree';
import SelectList from '../comps/SelectList';
import { ModelPropertyMutator } from '@/api/generator/model-property-modify';

const comp = {
  name: 'comp-select-value',
  components: {
    'm-modal': Modal,
    'm-attr-tip': AttrTip,
    'm-select-tree': SelectTree,
    'm-list': SelectList
  },
  props: {
    currentId: String,
    filterCondtion: String,
    propertyKey: [Object, String], //// 当是Stereotype的定义的属性是，proertyKey值为IProperty对象，否则为字符串
    selectedElement: Object,
    isNodeSelectable: Function,
    shouldBeCut: Function,
    isRequired: {
      type: Boolean,
      default: false
    }
  },
  data() {
    const treeData = this.formatTreeData(this.getTreeData());
    if (this.filterCondtion || this.isNodeSelectable) {
      this.filterDisabled(treeData);
    }
    let selectedItem;
    if (this.currentId){
      const node = findNodeByValue(treeData, this.currentId);
      if (node && !node.disabled) {
        selectedItem = node;
      }
    }

    return {
      visible: false,
      treeData,
      list: this.getList(treeData),
      selectedNode: selectedItem,
      curTab: 'tree',
      selectOptions: []
      //// defaultSelectedNodes: selectedItem ? [selectedItem] : [],
      //// selectInfo: {
      ////   treeSelectItem: selectedItem,
      ////   listSelectItem: selectedItem,
      ////   curTab: 'tree'
      //// }
    };
  },
  mounted() {
    this.visible = true;
  },

  methods: {
    handleOk() {
      const selectedItem = this.getSelectedItem();
      this.visible = false;
      this.$emit('sure', selectedItem);
      //// if (selectedItem) {
      ////   this.visible = false;
      ////   this.$emit('sure', selectedItem);
      //// } else {
      ////   this.$message.error('请选择元素');
      ////   //// TODO: 没有选择节点
      //// }
    },
    handleCancel() {
      this.visible = false;
      this.$emit('close');
    },

    getTreeData() {

      return [app.sysmlModel];
    },
    formatTreeData(data) {
      //// const result = [];
      //// const map = {};
      //// treeForEach((node, parent) => {
      ////   map[node.id] = {
      ////     graphNode: node,
      ////     get displayTitle(){
      ////       return node.displayTitle;
      ////     },
      ////     get iconPath(){
      ////       return node.iconPath;
      ////     },
      ////     disabled: !ModelPropertyMutator.isNodeSelectable(
      ////       this.selectedElement,
      ////       this.propertyKey,
      ////       node.model,
      ////       this.filterCondtion
      ////     ),
      ////     selected: this.currentId && this.currentId === node.id

      ////   };

      //// });
      const tree = initTree(data, {
        labelKey: '1',
        valueKey: 'id',
        clean: true,
        keepParent: true,
        cutomFn: (node, source) => {
          //// node.scopedSlots = { title: 'default' };
          //// node.iconPath = source.iconPath;
          //// node.value = source.value;
          node.graphNode = source;
          node.getTypeName = function(){
            return node.graphNode.getTypeName();
          };
          Object.defineProperty(node, 'displayTitle', {
            get(){
              return source.displayTitle;
            }
          });
          Object.defineProperty(node, 'iconPath', {
            get(){
              return source.iconPath;
            }
          });
          //// node.displayTitle = source.displayTitle;
          if (this.isNodeSelectable){
            node.disabled =  !this.isNodeSelectable(source);

          } else {
            node.disabled =  !ModelPropertyMutator.isNodeSelectable(
              this.selectedElement,
              this.propertyKey,
              source,
              this.filterCondtion
            );

          }

          node.selected = this.currentId && this.currentId === source.value;
          node.expand = false;
          node.id = source.id;
        }
      });
      tree[0] && (tree[0].expand = true);
      console.log("tree", tree);
      return tree;
    },
    getList(treeData) {
      const list = [];
      treeForEach(treeData, node => {
        if (node.disabled) return;
        list.push(node);
      });
      return list;
    },
    handleTreeSelect(model) {
      if (this.selectedNode && model === this.selectedNode && !this.isRequired){
        this.selectedNode.selected = false;
        this.selectedNode = undefined;
        return;
      }
      this.selectedNode && ( this.selectedNode.selected = false);
    
      model.selected = true;
      this.selectedNode = model;
    },
    handleListSelect(model) {
      this.handleTreeSelect(model);
      //// this.selectedNode = model;
    },
    getSelectedItem() {
      return this.selectedNode;
      //// return this.selectInfo.curTab == 'tree'
      ////   ? this.selectInfo.treeSelectItem
      ////   : this.selectInfo.listSelectItem;
    },
    isAllDisabled(node) {
      if (!node.disabled) return false;
      if (this.shouldBeCut && this.shouldBeCut(node)) return false;
      let allDisabled = true;
      node.children &&
        treeForEach(node.children, node => {
          if (!node.disabled) {
            allDisabled = false;
            return false;
          }
        });
      return allDisabled;
    },
    filterDisabled(treeData) {
      treeForEach(treeData, (node, parent) => {
        if (node.children) {
          for (let i = 0; i < node.children.length; i++) {
            if (this.isAllDisabled(node.children[i])) {
              node.children.splice(i, 1);
              i--;
            }
          }
        }
        return treeData;
      });
    },
    handleSelectSearch: debounce(function(query){
      console.log(query);
      const flatData = [];
      if (query === '' ) return flatData;
      query = query.toLowerCase();
      treeForEach(this.treeData, i => {
        const name = !i.disabled && i.graphNode.model && ( i.graphNode.model.name ||  i.graphNode.model.body ||  i.graphNode.title);
        if (name && name.toLowerCase().includes(query)) {

          flatData.push({ label: i.graphNode.title, id: i.graphNode.id });
        };
      });
      this.selectOptions = flatData;

    }, 200),
    handleSelectChange(id){
      console.log(id);
      const result = this.list.find(it => it.id === id);
      this.handleTreeSelect(result);
      //// result.selected = true;
      this.expandParent(result);

      //// const graphNode = id && graphHelper.getGraphNodeById(id, app.activeProjectId);
      //// if (graphNode) {
      ////   this.handleSelect(graphNode);
      //// }
      this.$nextTick(() => {
        let wrapperClass =  this.curTab === 'tree' ? '.v-select-tree' : '.v-select-list';
       
        const dom = document.querySelector(wrapperClass + ' #v' + result.id); 
        if (dom){
          dom.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" });
        }
      });

    },
    expandParent(node){
     
      if (node.parent){
        node.parent.expand = true;
        this.expandParent(node.parent);
      }

    }

  }
};
export default comp;
export const selectValue = new Portal(comp, { single: true });
export const portal = selectValue;

</script>
<style lang="scss" scoped>
._tab {
  padding-left: 22px;
  padding-right: 22px;
  padding-top: 17px;
}
</style>
